#include "linklist.h"
#include <stdlib.h>
#include <stdio.h>
#include "printelem.h"

void initLinkList(LinkList *L)
{
    if (L == NULL)
        return;

    *L = (LinkList)malloc(sizeof(LinkNode));
    (*L)->next = NULL;
}

void destroyLinkList(LinkList *L)
{
    if (L == NULL || (*L) == NULL)
        return;

    clearLinkList(L);
    free(*L);
    *L = NULL;
}

void clearLinkList(LinkList *L)
{
    if (L == NULL || (*L) == NULL)
        return;

    while ((*L)->next != NULL)
    {
        LinkList p = (*L)->next;
        (*L)->next = p->next;
        free(p);
    }
}

int linklistIsEmpty(LinkList *L)
{
    if (L == NULL || (*L) == NULL)
        return 1;

    return (*L)->next == NULL ? 1 : 0;
}

int linklistLength(LinkList *L)
{
    if (L == NULL || (*L) == NULL)
        return 0;

    int result = 0;
    LinkList p = *L;
    while (p->next != NULL)
    {
        result++;
        p = p->next;
    }

    return result;
}

int getLinkListElem(LinkList *L, int i, ElemType *e)
{
    if (L == NULL || (*L) == NULL)
        return 0;

    int j = -1;
    LinkList p = *L;
    while (j < i && p != NULL)
    {
        j++;
        p = p->next;
    }

    if (j == i && p != NULL)
    {
        *e = p->data;
        return 1;
    }

    return 0;
}

int locateLinkListElem(LinkList *L, ElemType e)
{
    if (L == NULL || (*L) == NULL)
        return -1;

    int result = 0;
    LinkList p = (*L)->next;
    while (p != NULL && p->data != e)
    {
        result++;
        p = p->next;
    }

    if (p == NULL)
        return -1;

    return result;
}

int priorLinkListElem(LinkList *L, ElemType cur_e, ElemType *pre_e)
{
    if (L == NULL || (*L) == NULL || (*L)->next == NULL)
        return 0;

    LinkList p = (*L)->next;
    LinkList q = p->next;
    while (q != NULL && q->data != cur_e)
    {
        p = q;
        q = p->next;
    }

    if (q == NULL)
        return 0;

    *pre_e = p->data;
    return 1;
}

int nextLinkListElem(LinkList *L, ElemType cur_e, ElemType *next_e)
{
    if (L == NULL || (*L) == NULL)
        return 0;

    LinkList p = (*L)->next;
    while (p != NULL && p->data != cur_e)
    {
        p = p->next;
    }

    if (p == NULL || p->next == NULL)
        return 0;

    *next_e = p->next->data;
    return 1;
}

int linklistInsert(LinkList *L, int i, ElemType e)
{
    if (L == NULL || (*L) == NULL)
        return 0;

    int j = 0;
    LinkList p = (*L);
    while (j < i && p != NULL)
    {
        j++;
        p = p->next;
    }

    if (p == NULL)
        return 0;

    LinkList q = (LinkList)malloc(sizeof(LinkNode));
    q->data = e;
    q->next = p->next;
    p->next = q;
    return 1;
}

int linklistDelete(LinkList *L, int i, ElemType *e)
{
    if (L == NULL || (*L) == NULL)
        return 0;

    int j = 0;
    LinkList p = (*L);
    while (j < i && p != NULL)
    {
        j++;
        p = p->next;
    }
    
    if (p == NULL || p->next == NULL)
        return 0;
    
    LinkList q = p->next;
    *e = q->data;

    p->next = q->next;
    free(q);
    return 1;
}

void traverseLinkList(LinkList *L)
{
    if (L == NULL || (*L) == NULL)
        return;

    LinkList p = (*L)->next;
    while (p != NULL)
    {
        printInt(p->data);
        printf("\t");
        p = p->next;
    }

    printf("\n");
}